home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / Screens / rsmac.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-19  |  31.1 KB  |  1,122 lines  |  [TEXT/CWIE]

  1. /*
  2.  *
  3.  *      Virtual Screen Kernel Macintosh Real Screen Interface
  4.  *                          (rsmac.c)
  5.  *
  6.  *   National Center for Supercomputing Applications
  7.  *      by Gaige B. Paulsen
  8.  *
  9.  *    This file contains the macintosh real screen calls for the NCSA
  10.  *  Virtual Screen Kernel.
  11.  *
  12.  *      RSbell(w)                   - Ring window w's bell
  13.  *      RScursoff(w)                - Turn the cursor off in w
  14.  *      RScurson(w,x,y)             - Turn the cursor on in w at x,y
  15.  *      RSdraw(w,x,y,a,len,ptr)     - Draw @x,y in w string@ptr for length len
  16.  *      RSdelchars(w,x,y,n)         - Delete n chars in w from x,y
  17.  *      RSdellines(w,t,b,n)         - Delete n lines in region t->b in w
  18.  *      RSerase(w,x1,y1,x2,y2)      - Erase from x1,y1 to x2,y2 in w
  19.  *      RSinitall()                 - Initialize the world if necessary
  20.  *      RSinslines(w,t,b,n)         - Insert n lines in region t->b in w
  21.  *      RSinsstring(w,x,y,a,len,ptr)- Insert len chars @x,y in w attrib a
  22.  *      RSsendstring(w,ptr,len)     - Send string @ptr length len from window w
  23.  *        RSbufinfo( w, total,current)- Tells you the total/current lines in buffer
  24.  *        RSmargininfo( w, total, current)    - Tells you total/current columns in VS
  25.  *
  26.  *
  27.  *  Macintosh only Routines:
  28.  *    NI    RSregnconv( *)                - Convert region to rect coords
  29.  *  NI  RSsetwind(w)                - Set the port and vars to window w
  30.  *  NI  RSsetattr(a)                - Set font/text style to a
  31.  *    NI    RSsetConst(w)
  32.  *    ML    RSattach(w,wind)            - Attach the RS (w) to window wind
  33.  *    ML    RSdetach(w)                - Ready window for go-away
  34.  *    ML    RSselect(w,pt,shift)        - Handle selection RS (w) point (pt) and (shift) if held down
  35.  *    ML    RSzoom(window,code,shifted)    - Zoom Box handling
  36.  *    ML    RSsize( window, where)        - Resize handling
  37.  *    IN    RSgetwindow(w)                - Get the WindowPtr for RS (w)
  38.  *    IN    RSfindvwind(wind)            - Find the (RS/VS) # of wind
  39.  *    IN    RSfindscroll( control, n)    - Find which VS the control is in and which control it is
  40.  *      RSupdate(wind)                - Handle updates on WIND, return 0 if not an RS
  41.  *        RSactivate(w)                - Handle activate events 
  42.  *        RSdeactivate(w)                - Handle deactivate events 
  43.  *        RSGetTextSel(w,table)        - Returns handle to text selection of window w, table->tabs
  44.  *        RSnewwindow( wDims, sb, wid, lines
  45.  *            name,wrap,fnum,fsiz,
  46.  *            showit, goaway)            - Returns VS # of newly created text window -
  47.  *                                      wDims (dimension),sb(scrollback),wid(width 80/132),
  48.  *                                    lines (# of lines, 24 <> 66),
  49.  *                                      name(window), wrap(0/1),fnum,fsiz, showit(vis),goaway(0,1)
  50.  *        RSkillwindow( w)            - Destroys, deallocates, kills window (w)
  51.  *        RSclick(window, eventRecord)- Handle clicks in window (returns false if not RS window)
  52.  *        RShide(w)                    - Hide RS (w)
  53.  *        RSshow(w)                    - Show RS (w)
  54.  *        RScprompt(w, FilterProc)    - Prompt for colors...FilterProc is for Modal Dialog
  55.  *        RSsetcolor(w,n,r,g,b)        - Set one of the 4 colors of RS (w) to R,G,B
  56.  *        RSgetcolor(w,n,r,g,b)        - Get one of the 4 colors of RS (w) into R,G,B
  57.  *        RSmouseintext(w,myPoint)    - Returns true if Mouse is in text part of current RS window
  58.  *        RSskip(w,on)                - Activate/deactivate drawing in an RS
  59.  *        
  60.  *        IN - Informational
  61.  *        ML - Mid Level
  62.  *        NI - Necessary Internal
  63.  *           - Suggested calls
  64.  *
  65.  *      Version Date    Notes
  66.  *      ------- ------  ---------------------------------------------------
  67.  *      0.01    861102  Initial coding -GBP
  68.  *      0.25    861106  Added code from screen.c -GBP
  69.  *      0.50    861113  First compiled edition -GBP
  70.  *        2.1        871130    NCSA Telnet 2.1 -GBP
  71.  *        2.2     880715    NCSA Telnet 2.2 -GBP
  72.  *        2.6        7/92    put globals into struct, cursors into array, and cleaned up 
  73.  *                        some of the font typedefs            Scott Bulmahn
  74.  *        2.6b4    12/92    Cleaned up the code, and added double clicking -- Scott Bulmahn
  75.  *
  76.  */
  77.  
  78. #ifdef MPW
  79. #pragma segment RS
  80. #endif
  81.  
  82. #define __ALLNU__
  83.  
  84. #include "DlogUtils.proto.h"
  85. #include "configure.proto.h"    // For colorboxmodalproc and colorboxproc
  86. #include "maclook.proto.h"
  87. #include "network.proto.h"
  88. #include "menuseg.proto.h"
  89. #include "vskeys.h"
  90. #include "vsdata.h"
  91. #include "vsinterf.proto.h"
  92. #include "vsintern.proto.h"
  93. #include "wind.h"
  94. #include "rsdefs.h"
  95. #include "parse.proto.h"        // For SendNAWSinfo proto
  96. #include "wdefpatch.proto.h"    /* 931112, ragge, NADA, KTH */
  97. #include "drag.proto.h"
  98. #include "rsinterf.proto.h"
  99. #include "event.proto.h" //notify user proto
  100. #define NFDEF {0,0,0}
  101. #define NBDEF {65535,65535,65535}
  102. #define BFDEF {0,61183,11060}
  103. #define BBDEF {61183,2079,4938}
  104. #define UFDEF {1,0,0}
  105. #define UBDEF {0,0,0}
  106.  
  107.  
  108. extern WindRec *screens;
  109.  
  110. #include "rsmac.proto.h"
  111.  
  112. short MaxRS;
  113.  
  114. RSdata *RSlocal, *RScurrent;
  115. Rect    noConst,
  116.         RScur;                /* cursor rectangle */
  117.  
  118. RgnHandle RSuRgn;            /* update region */
  119.  
  120. short RSw=-1,         /* last window used */
  121.     RSa=0;          /* last attrib used */
  122. extern long RScolors[];
  123.  
  124. // initializes handling of terminal windows
  125. void RSinitall(short max) //max windows to allow
  126. {
  127.     short i;
  128.     MaxRS = max;
  129.     RSlocal = (RSdata *) myNewPtr(MaxRS * sizeof(RSdata));
  130.     for (i = 0; i < MaxRS; RSlocal[i++].window = 0L)
  131.     {
  132.         RScurrent = RSlocal + i;
  133.         RScurrent->id = 'RSDA';
  134.         RScurrent->cursor.top = 0;
  135.         RScurrent->cursor.bottom = 0;
  136.         RScurrent->cursor.left = 0;
  137.         RScurrent->cursor.right = 0;
  138.     }
  139.     RSuRgn = NewRgn();
  140.     RScur.left = 0;
  141.     RScur.top = 0;
  142.     RScur.bottom = 0;
  143.     RScur.right = 0;
  144.     if (!TelInfo->haveColorQuickDraw)
  145.         DisposeHandle((Handle)TelInfo->AnsiColors);
  146.         
  147.  
  148. } // RSinitall
  149.  
  150.  
  151. void RSsetConst
  152.   (
  153.     short w
  154.   )
  155.   /* sets "noConst" global to a zero-based rectangle equal in size
  156.     to the specified terminal window. */
  157.   {
  158.   noConst.left = 0;
  159.   noConst.top = 0;
  160.   noConst.right = RSlocal[w].width;
  161.   noConst.bottom = RSlocal[w].height;
  162.   } /* RSsetConst */
  163.  
  164. /****************************************************************************/
  165. /*  Given a window record number, do a SetPort() to the window associated with
  166. *   that window record.
  167. */
  168. short RSsetwind
  169.   (
  170.     short w
  171.   )
  172.   {
  173.     if ((w < 0) || (w > MaxRS))
  174.         return(-3);
  175.     if (RSw != w)                                /* if last window used is different */
  176.       {
  177.         if (RSlocal[w].window == 0L)
  178.             return(-4);
  179.         RScurrent = RSlocal + w;
  180.         RSw = w;
  181.         RSa = -1; /* attributes will need setting */
  182.         SetPort(RScurrent->window);
  183.         return(1);
  184.       }
  185.     SetPort(RScurrent->window);
  186.     return(0);
  187.   } /* RSsetwind */
  188.  
  189. void RSvalidateRect(short w)
  190. {
  191.     ValidRect(&((RSlocal[w].window)->portRect));
  192. }
  193. void RSbell
  194.   (
  195.     short w
  196.   )
  197.   /* gives an audible signal associated with the specified window. */
  198.   {
  199.     RSsetwind(w);
  200.     if (FrontWindow() != RScurrent->window)
  201.       {
  202.       /* beep and temporarily invert the window contents, so
  203.         the user sees which window is beeping */
  204.         InvertRect(&RScurrent->window->portRect);
  205.         SysBeep(8);
  206.         InvertRect(&RScurrent->window->portRect);
  207.       }
  208.     else
  209.       /* window is frontmost--just beep */
  210.         SysBeep(8);
  211.      NotifyUser();
  212.  
  213.   } /* RSbell */
  214.  
  215.  
  216. void RScursoff
  217.   (
  218.     short w
  219.   )
  220.   /* hides the text cursor for the specified window. Assumes it
  221.     is currently being shown. */
  222.   {
  223.     if (RSlocal[w].skip || !RSlocal[w].cursorstate)        /* BYU 2.4.11 */
  224.         return;
  225.     RSsetwind(w);
  226.     RScurrent->cursorstate = 0;                            /* BYU 2.4.11 */
  227.     InvertRect(&RScurrent->cursor);
  228.   } /* RScursoff */
  229.  
  230. void RScurson
  231.   (
  232.     short w,
  233.     short x,
  234.     short y
  235.   )
  236.   /* displays the text cursor for the specified window, at the
  237.     specified position. Assumes it isn't currently being shown. */
  238.   {
  239.     if (RSlocal[w].skip || RSlocal[w].cursorstate)        /* BYU 2.4.11 */
  240.         return;
  241.     RSsetwind(w);
  242.  
  243.     RScurrent->cursor.left = x * RScurrent->fwidth;            /* BYU 2.4.11 */
  244.     RScurrent->cursor.top  = y * RScurrent->fheight;        /* BYU 2.4.11 */
  245.  
  246.     switch (gApplicationPrefs->CursorType) {                                            /* BYU 2.4.11 */
  247.         case UNDERSCORECURSOR:                                        /* BYU 2.4.11 */
  248.             RScurrent->cursor.top  += RScurrent->fheight;            /* BYU 2.4.11 */
  249.             RScurrent->cursor.right  = RScurrent->cursor.left + RScurrent->fwidth;    /* BYU 2.4.11 */
  250.             RScurrent->cursor.bottom = RScurrent->cursor.top + 1;    /* BYU 2.4.11 */
  251.             break;
  252.         case VERTICALCURSOR:                                        /* BYU 2.4.11 */
  253.             RScurrent->cursor.left += 2;                            /* BYU 2.4.11 */
  254.             RScurrent->cursor.right  = RScurrent->cursor.left + 1;    /* BYU 2.4.11 */
  255.             RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight;    /* BYU 2.4.11 */
  256.             break;
  257.         case BLOCKCURSOR:                                            /* BYU 2.4.11 */
  258.         default:                                                    /* BYU 2.4.11 */
  259.             RScurrent->cursor.right  = RScurrent->cursor.left + RScurrent->fwidth;    /* BYU 2.4.11 */
  260.             RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight;    /* BYU 2.4.11 */
  261.             break;
  262.     }
  263.  
  264.     if (!gApplicationPrefs->BlinkCursor) {                                    /* BYU 2.4.11 */
  265.         RScurrent->cursorstate = 1;                        /* BYU 2.4.11 */
  266.         InvertRect(&RScurrent->cursor);                    /* BYU 2.4.11 */
  267.     }                                                    /* BYU 2.4.11 */
  268.   } /* RScurson */
  269.  
  270.  
  271. void RSsetattr(short a)
  272. {
  273.      short fg, bg;
  274.       
  275.      static GrafPtr lastPort;    
  276.     
  277.     if (RSa!=-1 && RSa==a && qd.thePort==lastPort) return;            
  278.     lastPort = qd.thePort;
  279.     RSa = a;                
  280.  
  281.     if (VSisgrph(a))
  282.         TextFont(74); /* use "NCSA VT" font for special graphics */
  283.     else
  284.         RSTextFont(RScurrent->fnum,RScurrent->fsiz,a);     /* BYU - use user-selected text font */
  285.  
  286.     TextSize(RScurrent->fsiz);
  287.  
  288. /* BYU - bold system fonts don't work (they overwrite the scroll bars), 
  289.          but NCSA's 9 point Monaco bold works okay. */
  290.  
  291.     TextFace((a & outline) >> 1);     /* BYU - do outline as underline setting */
  292.     
  293.     if (VSisansifg(a)) 
  294.         fg = 4 +((a>>8)&0x7);
  295.         //if (a&VSa(vsBold)) fg += 8;
  296.     else 
  297.         fg = 0;
  298.     
  299.     if (VSisansibg(a))
  300.         bg = 4+ ((a>>12)&0x7);
  301.     else
  302.         bg = 1;
  303.   
  304.       // set up text modes 
  305.  
  306.     if (TelInfo->haveColorQuickDraw)
  307.     {
  308.         if (VSisrev(a))
  309.             TextMode(notSrcCopy);
  310.         else
  311.             TextMode(srcCopy);
  312.     }
  313.     else
  314.     {
  315.         if (VSisrev(a))
  316.         {
  317.             BackPat(PATTERN(qd.black));    /* Reverses current attributes regard */
  318.             PenPat(PATTERN(qd.white));    /* less of the color, etc.... */
  319.         }
  320.         else
  321.         {
  322.             BackPat(PATTERN(qd.white));    /* Reverses current attributes regard */
  323.             PenPat(PATTERN(qd.black));    /* less of the color, etc.... */
  324.         } 
  325.     }
  326.     
  327.     //set up colors
  328.     if (TelInfo->haveColorQuickDraw) 
  329.     {
  330.         if (VSisblnk(a))
  331.         {
  332.             PmForeColor(2);                //use colors for blink
  333.             PmBackColor(3);
  334.         }
  335.         else
  336.         {
  337.             PmForeColor(fg);
  338.             PmBackColor(bg);
  339.         }
  340.     }
  341.     else 
  342.     {
  343.         if (VSisblnk(a))
  344.         {
  345.             ForeColor(RScolors[7]);    //use colors for blink
  346.             BackColor(RScolors[0]);    
  347.         }
  348.         else
  349.         {
  350.             ForeColor(RScolors[0]);
  351.             BackColor(RScolors[7]);
  352.         }
  353.     }
  354.     
  355. } /* RSsetattr */
  356.  
  357.  
  358. void RSTextFont(short myfnum, short myfsiz, short myface)                 /* BYU */
  359. {                                        /* BYU */
  360.     if ((myfnum == monaco) &&             /* BYU - If Monaco, size 9, and bold, then */
  361.         (myfsiz == 9) &&                /* BYU */
  362.         (myface & bold))    {            /* BYU */
  363.         TextFont(75);                    /* BYU - use NCSA's Monaco. */
  364.     } else {                            /* BYU */
  365.         TextFont(myfnum);                /* BYU */
  366.     }                                    /* BYU */
  367. }                                        /* BYU */
  368.  
  369.  
  370. #ifdef    NO_UNIVERSAL
  371. #define LMGetHiliteMode() (* (unsigned char *) 0x0938)
  372. #define LMSetHiliteMode(HiliteModeValue) ((* (unsigned char *) 0x0938) = (HiliteModeValue))
  373. #endif
  374.  
  375. void DoHiliteMode(void)        /* BYU LSC */
  376.   /* enables use of highlighting in place of simple color inversion
  377.     for next QuickDraw operation. */
  378.   {
  379.       
  380.       LMSetHiliteMode(LMGetHiliteMode() & 0x7F);
  381. //    char *p = (char *) 0x938; /* pointer to HiliteMode low-memory global */
  382. //    *p = *p & 0x7f; /* clear the HiliteBit */
  383.   } /* HiliteMode */
  384.  
  385. void RSinvText
  386.   (
  387.     short w, 
  388.     Point curr,
  389.     Point last,
  390.     RectPtr constrain /* don't highlight anything outside this rectangle */
  391.   )
  392.   /* highlights the text from curr to last inclusive. */
  393.   {
  394.     Rect temp, temp2;
  395.     Point lb, ub;
  396.  
  397.     RSsetwind(w);
  398.   /* normalize coordinates with respect to visible area of virtual screen */
  399.     curr.v -= RScurrent->topline;
  400.     curr.h -= RScurrent->leftmarg;
  401.     last.v -= RScurrent->topline;
  402.     last.h -= RScurrent->leftmarg;
  403.  
  404.     if (curr.v == last.v)
  405.       {
  406.       /* highlighted text all on one line */
  407.         if (curr.h < last.h) /* get bounds the right way round */
  408.           {
  409.             ub = curr;
  410.             lb = last;
  411.           }
  412.         else
  413.           {
  414.             ub = last;
  415.             lb = curr;
  416.           } /* if */
  417.         MYSETRECT /* set up rectangle bounding area to be highlighted */
  418.           (
  419.             temp,
  420.             (ub.h + 1) * RScurrent->fwidth,
  421.             ub.v * RScurrent->fheight,
  422.             (lb.h + 1) * RScurrent->fwidth,
  423.             (lb.v + 1) * RScurrent->fheight
  424.           );
  425.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  426.         DoHiliteMode();                        /* BYU LSC */
  427.         InvertRect(&temp2);
  428.       }
  429.     else
  430.       {
  431.       /* highlighting across more than one line */
  432.         if (curr.v < last.v)
  433.             ub = curr;
  434.         else
  435.             ub = last;
  436.         if (curr.v > last.v)
  437.             lb = curr;
  438.         else
  439.             lb = last;
  440.         MYSETRECT /* bounds of first (possibly partial) line to be highlighted */
  441.           (
  442.             temp,
  443.             (ub.h + 1) * RScurrent->fwidth,
  444.             ub.v * RScurrent->fheight,
  445.             RScurrent->width,
  446.             (ub.v + 1) * RScurrent->fheight
  447.           );
  448.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  449.         DoHiliteMode();                        /* BYU LSC */
  450.         InvertRect(&temp2);
  451.         MYSETRECT /* bounds of last (possibly partial) line to be highlighted */
  452.           (
  453.             temp,
  454.             0,
  455.             lb.v * RScurrent->fheight,
  456.             (lb.h + 1) * RScurrent->fwidth,
  457.             (lb.v + 1) * RScurrent->fheight
  458.           );
  459.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  460.         DoHiliteMode();                        /* BYU LSC */
  461.         InvertRect(&temp2);
  462.  
  463.         if (lb.v - ub.v > 1) /* highlight extends across more than two lines */
  464.           {
  465.           /* highlight complete in-between lines */
  466.             SetRect
  467.               (
  468.                 &temp,
  469.                 0,
  470.                 (ub.v + 1) * RScurrent->fheight,
  471.                 RScurrent->width,
  472.                 lb.v * RScurrent->fheight
  473.               );
  474.             SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  475.             DoHiliteMode();                        /* BYU LSC */
  476.             InvertRect(&temp2);
  477.  
  478.           } /* if */
  479.       } /* if */
  480.   } /* RSinvText */
  481.  
  482. void RSdraw
  483.   (
  484.     short w, /* window number */
  485.     short x, /* starting column */
  486.     short y, /* line on which to draw */
  487.     short a, /* text attributes */
  488.     short len, /* length of text to draw */
  489.     char *ptr /* pointer to text */
  490.   )
  491.   /* draws a piece of text (assumed to fit on a single line) in a window,
  492.     using the specified attributes. If any part of the text falls
  493.     within the current selection, it will be highlighted. */
  494.   {
  495.     Rect rect;
  496.     short ys;
  497.  
  498.     if (RSlocal[w].skip)
  499.         return;
  500.     RSsetwind(w);
  501. //    RSsetattr(0);        JMB 2.6.1d4
  502.  
  503.     ys = y * RScurrent->fheight;
  504.     MYSETRECT /* set up rectangle bounding text being drawn */
  505.       (
  506.         rect,
  507.         x * RScurrent->fwidth,
  508.         ys,
  509.         (x + len) * RScurrent->fwidth,
  510.         ys + RScurrent->fheight
  511.       );
  512.  
  513.     RSsetattr(a);
  514.  
  515.     if (x <= 0)            /* BYU 2.4.12 - Without this, 1 pixel column of reverse */
  516.       rect.left = -3;    /* BYU 2.4.12 - video text does not clear at left margin */
  517.  
  518.     if (rect.bottom == RScurrent->rheight)
  519.         rect.bottom += 1; //CCP take care of updating problems while scrolling
  520.     EraseRect(&rect);
  521.  
  522.     if (x <= 0)            /* BYU 2.4.12 - Okay, just putting it back the way it was */
  523.       rect.left = 0;    /* BYU 2.4.12 */
  524.  
  525.     MoveTo(x * RScurrent->fwidth, ys + RScurrent->fascent);
  526.     
  527.     DrawText(ptr, 0, len);
  528.  
  529.     if (RScurrent->selected)
  530.         RSinvText(w, *(Point *) &RScurrent->anchor,
  531.             *(Point *) &RScurrent->last, &rect);
  532.     ValidRect(&rect);
  533.   } /* RSdraw */
  534.  
  535. void RSdelcols
  536.   (
  537.     short w,
  538.     short n /* number of columns to scroll */
  539.   )
  540.   /* scrolls the entire visible display of a virtual screen the
  541.     specified number of columns to the left, blanking out
  542.     the newly-revealed area. */
  543.   {
  544.     Rect rect;
  545.  
  546.     if (RSlocal[w].skip)
  547.         return;
  548.     RSsetwind(w);
  549.     MYSETRECT /* bounds of entire text area, for scrolling */
  550.       (
  551.         rect,
  552.         0,
  553.         0,
  554.         RScurrent->width,
  555.         RScurrent->height
  556.       );
  557.     ScrollRect(&rect, -n * RScurrent->fwidth, 0, RSuRgn);
  558.     InvalRgn(RSuRgn);
  559.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  560.     MYSETRECT /* bounds of newly-revealed area */
  561.       (
  562.         rect,
  563.         RScurrent->width - (n * RScurrent->fwidth),
  564.         0,
  565.         RScurrent->width,
  566.         RScurrent->height
  567.       );
  568.     if (RScurrent->selected)
  569.       /* highlight any newly-revealed part of the current selection */
  570.         RSinvText(w, *(Point *) &RScurrent->anchor,
  571.             *(Point *) &RScurrent->last, &rect);
  572.   } /* RSdelcols */
  573.  
  574. void RSdelchars
  575.   (
  576.     short w, /* affected window */
  577.     short x, /* column to delete from */
  578.     short y, /* line on which to do deletion */
  579.     short n /* number of characters to delete */
  580.   )
  581.   /* deletes the specified number of characters from the specified
  582.     position to the right, moving the remainder of the line to the
  583.     left. */
  584.   {
  585.     Rect rect;
  586.  
  587.     if (RSlocal[w].skip)
  588.         return;
  589.     RSsetwind(w);
  590.     RSsetattr(0); /* avoid funny pen modes */
  591.     MYSETRECT /* bounds of area from starting column to end of line */
  592.       (
  593.         rect,
  594.         x * RScurrent->fwidth,
  595.         y * RScurrent->fheight,
  596.         RScurrent->width,
  597.         (y + 1) * RScurrent->fheight
  598.       );
  599.     if ((x + n) * RScurrent->fwidth > RScurrent->width)
  600.       /* deleting to end of line */
  601.         EraseRect(&rect);
  602.     else
  603.       {
  604.       /* scroll remainder of line to the left */
  605.         ScrollRect(&rect, - RScurrent->fwidth * n, 0, RSuRgn);
  606.         InvalRgn(RSuRgn);
  607.            ValidRect(&rect); /* leave newly-revealed area blank */
  608.         if (RScurrent->selected)
  609.           {
  610.           /* highlight any part of selection which lies in newly-blanked area */
  611.             HLock((Handle) RSuRgn);
  612.             RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &((*RSuRgn)->rgnBBox));
  613.             HUnlock((Handle) RSuRgn);
  614.           } /* if */
  615.       } /* if */
  616.   } /* RSdelchars */
  617.  
  618. void RSdellines
  619.   (
  620.     short w, /* affected window */
  621.     short t, /* top line of affected region */
  622.     short b, /* bottom line of affected region */
  623.     short n, /* number of lines to delete */
  624.     short scrolled
  625.       /*
  626.         -ve => cancel current selection, if any;
  627.         +ve => selection has moved up one line;
  628.         0 => don't touch selection
  629.       */
  630.   )
  631.   /* deletes lines at the top of the specified region of a window,
  632.     inserting new blank lines at the bottom, and scrolling up the
  633.     stuff in between. */
  634.   {
  635.     Rect    rect;
  636.     short    RSfheightTimesn, RSfheightTimesbplus1;
  637.  
  638.     if (RSlocal[w].skip)
  639.         return;
  640.  
  641.     RSsetwind(w);
  642.     RSsetConst(w);
  643.     RSsetattr(0); /* avoid funny pen modes */
  644.  
  645.     if (scrolled)
  646.       {
  647.         if (RScurrent->selected && scrolled < 0)
  648.           {
  649.           /* unhighlight and cancel current selection */
  650.             RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &noConst);
  651.             RScurrent->selected = 0;
  652.           }
  653.         else
  654.           {
  655.             RScurrent->last.v -= 1;        /* Subtract one from each of the */
  656.             RScurrent->anchor.v -= 1;    /* vertical Selection components */
  657.           } /* if */
  658.       } /* if */
  659.  
  660.     rect.left = -1;                            /* BYU 2.4.12 - necessary */
  661.     rect.right = RScurrent->width;
  662.     rect.top = t * RScurrent->fheight;
  663.     RSfheightTimesbplus1 = (b + 1) * RScurrent->fheight;
  664.     rect.bottom = RSfheightTimesbplus1;
  665.   /* adjust the update region to track the scrolled window contents */
  666.       RSfheightTimesn = RScurrent->fheight * n;
  667.     OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn,
  668.         0, -RSfheightTimesn);
  669.     ScrollRect(&rect, 0, -RSfheightTimesn , RSuRgn);
  670.     RSsetattr(VSIw->attrib); /* restore mode for text drawing */
  671.     InvalRgn(RSuRgn);
  672.  
  673.   /* validate the area containing the newly-inserted blank lines. */
  674.   /* any necessary redrawing in newly-revealed area will be done by caller */
  675.     MYSETRECT
  676.       (
  677.         rect,
  678.         0,
  679.         (b - n + 1) * RScurrent->fheight - 1,
  680.         RScurrent->width,
  681.         RSfheightTimesbplus1 + 1
  682.       );
  683.       ValidRect(&rect);
  684.   } /* RSdellines */
  685.  
  686. void RSerase
  687.   (
  688.     short w, /* affected window */
  689.     short x1, /* left column */
  690.     short y1, /* top line */
  691.     short x2, /* right column */
  692.     short y2 /* bottom line */
  693.   )
  694.   /* erases a rectangular portion of the screen display, preserving
  695.     the selection highlight. */
  696.   {
  697.     Rect rect;
  698.  
  699.     if (RSlocal[w].skip)
  700.         return;
  701.     RSsetwind(w);
  702.     RSsetattr(0); /* avoid funny pen modes */
  703.     SetRect
  704.       (
  705.         &rect,
  706.         x1 * RScurrent->fwidth ,
  707.         y1 * RScurrent->fheight,
  708.         (x2 + 1) * RScurrent->fwidth - 1,
  709.         (y2 + 1) * RScurrent->fheight + 1
  710.       );
  711.     if (rect.left <= 0)                        /* little buffer strip on left */
  712.         rect.left = CHO;
  713.     if (rect.right >= RScurrent->width - 1)
  714.         rect.right = RScurrent->rwidth - 2;    /* clear to edge of window, including edge strip */
  715.     if (rect.bottom >= RScurrent->height - 2)
  716.         rect.bottom = RScurrent->rheight + 1;    /* clear to bottom edge also */
  717.     EraseRect(&rect);
  718.     if (RScurrent->selected)
  719.       /* highlight any part of the selection within the cleared area */
  720.         RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect);
  721.   } /* RSerase */
  722.  
  723. void RSinslines
  724.   (
  725.     short w, /* affected window */
  726.     short t, /* where to insert blank lines */
  727.     short b, /* bottom of area to scroll */
  728.     short n, /* number of lines to insert */
  729.     short scrolled /* -ve <=> cancel current selection, if any */
  730.   )
  731.   /* inserts blank lines at the top of the given area of the display,
  732.     scrolling the rest of it down. */
  733.   {
  734.     Rect rect;
  735.  
  736.     if (RSlocal[w].skip)
  737.         return;
  738.     RSsetwind(w);
  739.     RSsetConst(w);
  740.     RSsetattr(0); /* avoid funny pen modes */
  741.     if (RScurrent->selected && (scrolled < 0))
  742.       {
  743.       /* unhighlight and cancel selection */
  744.         RSinvText(w, *(Point *) &RScurrent->anchor,
  745.             *(Point *) &RScurrent->last, &noConst);
  746.         RScurrent->selected = 0;
  747.       } /* if */
  748.     rect.left = -1;                        /* BYU 2.4.12 - necessary */
  749.     rect.right = RScurrent->width;
  750.     rect.top = t * RScurrent->fheight;
  751.     rect.bottom = (b + 1) * RScurrent->fheight;
  752.   /* adjust the update region to track the scrolled window contents */
  753.     OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn,
  754.         0, RScurrent->fheight * n);
  755.     ScrollRect(&rect, 0, RScurrent->fheight * n, RSuRgn);
  756.     InvalRgn(RSuRgn);
  757.   /* newly-inserted area is already blank -- validate it to avoid redrawing. */
  758.   /* any necessary redrawing will be done by caller */
  759.     SetRect(&rect, 0, t * RScurrent->fheight - 1,
  760.         RScurrent->width, (t + n) * RScurrent->fheight + 1);
  761.     ValidRect(&rect);
  762.   } /* RSinslines */
  763.  
  764. void RSinscols
  765.   (
  766.     short w,
  767.     short n /* number of columns to insert */
  768.   )
  769.   /* inserts blank columns at the left side of the text display in
  770.     the specified window, scrolling its current contents to the right.
  771.     Maintains the selection highlight, but doesn't move the selection.
  772.     Doesn't even unhighlight text which moves out of the selection area. */
  773.   {
  774.     Rect rect;
  775.  
  776.     if (RSlocal[w].skip)
  777.         return;
  778.     RSsetwind(w);
  779.     SetRect /* bounds of entire text area */
  780.       (
  781.         &rect,
  782.         0,
  783.         0,
  784.         RScurrent->width,
  785.         RScurrent->height
  786.       );
  787.     ScrollRect(&rect, n * RScurrent->fwidth, 0, RSuRgn);
  788.     InvalRgn(RSuRgn);
  789.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  790.     SetRect /* bounds of newly-inserted blank area */
  791.       (
  792.         &rect,
  793.         0,
  794.         0,
  795.         (n + 1) * RScurrent->fwidth - 1,
  796.         RScurrent->height
  797.       );
  798.     if (RScurrent->selected)
  799.       /* highlight any part of the selection in the newly-blanked area */
  800.         RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect);
  801.   } /* RSinscols */
  802.  
  803. void RSinsstring
  804.   (
  805.     short w, /* affected window */
  806.     short x, /* starting column at which to insert */
  807.     short y, /* line on which to insert */
  808.     short a, /* attributes for inserted text */
  809.     short len, /* length of inserted text */
  810.     char *ptr /* pointer to inserted text */
  811.   )
  812.   /* inserts a string of characters at the specified position, scrolling
  813.     the rest of the line to the right. Highlights any part of the newly-
  814.     inserted text lying within the current selection. */
  815.   {
  816.     Rect rect;
  817.  
  818.     if (RSlocal[w].skip)
  819.         return;
  820.     RSsetwind(w);
  821.     SetRect /* bounds of part of line from specified position to end of line */
  822.       (
  823.         &rect,
  824.         x * RScurrent->fwidth,
  825.         y * RScurrent->fheight,
  826.         RScurrent->width,
  827.         (y + 1) * RScurrent->fheight
  828.       );
  829.     ScrollRect(&rect, len * RScurrent->fwidth, 0, RSuRgn); /* scroll remainder of line to the right */
  830.     if (RSa != a)
  831.         RSsetattr(a);
  832.     InvalRgn(RSuRgn);
  833.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  834.     SetRect /* bounds area to contain inserted string */
  835.       (
  836.         &rect,
  837.         x * RScurrent->fwidth,
  838.         y * RScurrent->fheight,
  839.         (x + len) * RScurrent->fwidth,
  840.         (y + 1) * RScurrent->fheight
  841.       );
  842.     EraseRect(&rect); /* erase area to appropriate background */
  843.     MoveTo
  844.       (
  845.         x * RScurrent->fwidth,
  846.         y * RScurrent->fheight + RScurrent->fascent
  847.       );
  848.     DrawText(ptr, 0, len);
  849.     if (RScurrent->selected)
  850.       /* highlight any part of selection covering the newly-inserted text */
  851.         RSinvText(w, *(Point *) &RScurrent->anchor,
  852.             *(Point *) &RScurrent->last, &rect);
  853.   } /* RSinsstring */
  854.  
  855.  
  856. void RSmargininfo
  857.   (
  858.     short w,
  859.     short total, /* number of invisible character positions (screen width less visible width) */
  860.     short current /* leftmost visible character position */
  861.   )
  862.   /* updates the horizontal scroll bar and associated variables
  863.     to reflect the current view of the virtual screen within the
  864.     specified window. */
  865.   {
  866.     RSlocal[w].leftmarg = current;            /* Adjust local vars */
  867.     if (RSlocal[w].lcurrent != current)
  868.         SetCtlValue(RSlocal[w].left, (RSlocal[w].lcurrent = current));
  869.     if (RSlocal[w].lmax != total)
  870.         SetCtlMax(RSlocal[w].left, (RSlocal[w].lmax = total));
  871.   } /* RSmargininfo */
  872.  
  873.  
  874. void RSbufinfo
  875.   (
  876.     short w, /* affected window */
  877.     short total, /* number of lines of scrollback */
  878.     short current, /* current topmost visible line */
  879.     short bottom /* current bottommost visible line */
  880.   )
  881.   /* readjusts the vertical scroll bar and associated variables
  882.     to reflect the current view of the virtual screen within the
  883.     specified window. */
  884.   {
  885.     RSdata *RSthis;
  886.     short newmax;
  887.  
  888.     RSthis = RSlocal + w;
  889.  
  890.     newmax = (VSgetlines(w) - 1) - (bottom - current);
  891.  
  892.     RSthis->topline = current;            /* Adjust local vars */
  893.     if (RSthis->min != -total)
  894.     {
  895.         if (RSthis->min == 0) //need to activate scrollbars
  896.             SetCtlMin(RSthis->scroll, (RSthis->min = -total));
  897.         
  898.         (**RSthis->scroll).contrlMin = (RSthis->min = -total);    // JMB 2.6.1d4
  899.     } /* if */
  900.  
  901.     if (RSthis->current != current)
  902.         SetCtlValue(RSthis->scroll, (RSthis->current = current));
  903.  
  904.     if (RSthis->max != newmax)
  905.         (**RSthis->scroll).contrlMax = (RSthis->max = newmax);    // JMB 2.6.1d4
  906.  
  907.   } /* RSbufinfo */
  908.  
  909.  
  910.  
  911.  
  912. short RSfindscroll                /* Find screen index by control*/
  913.   (
  914.     ControlHandle control,
  915.     short *n
  916.   )
  917.   /* finds the window to which the given scroll bar belongs.
  918.     Returns the window number in *n if found, and a function
  919.     result of 1 for a vertical scroll bar, 2 for a horizontal
  920.     one, or -1 if the window wasn't found. */
  921.   {
  922.   /* look for a vertical scroll bar */
  923.     *n = 0;
  924.     while ((*n < MaxRS) && (control != RSlocal[*n].scroll))
  925.         (*n)++;
  926.     if (*n < MaxRS)
  927.         return (1); /* found it */
  928.   /* look for a horizontal scroll bar */
  929.     *n = 0;
  930.     while ((*n < MaxRS) && (control != RSlocal[*n].left))
  931.         (*n)++;
  932.     if (*n < MaxRS)
  933.         return (2); /* found it */
  934.     return(-1); /* not found */
  935.   } /* RSfindscroll */
  936.  
  937. void RSregnconv
  938.   (
  939.     RgnHandle regn,
  940.     short *x1, /* left (output) */
  941.     short *y1, /* top (output) */
  942.     short *x2, /* right (output) */
  943.     short *y2, /* bottom (output) */
  944.     short fh, /* font character height */
  945.     short fw /* font character width */
  946.   )
  947.   /* converts the bounding box of the specified QuickDraw region
  948.     into units of character positions (using the specified character
  949.     height and width) and returns the results in *x1, *y1, *x2 and *y2. */
  950.   {
  951.     HLock((Handle) regn);
  952.     *y1 = ((*regn)->rgnBBox.top) / fh;
  953.     *y2 = (((*regn)->rgnBBox.bottom) + fh - 1) / fh;
  954.     *x1 = ((*regn)->rgnBBox.left) / fw;
  955.     *x2 = (((*regn)->rgnBBox.right) + fw - 1) / fw;
  956.     HUnlock((Handle) regn);
  957.     if (*x1 < 0)
  958.         *x1 = 0;
  959.     if (*y1 < 0)
  960.         *y1 = 0;
  961.     if (*x2 < 0)
  962.         *x2 = 0;
  963.     if (*y2 < 0)
  964.         *y2 = 0;
  965.   } /* RSregnconv */
  966.  
  967.  
  968.  
  969. #define    Fwidthhalf    FWidth/2
  970.  
  971. Point normalize(Point in, short w, Boolean autoScroll)
  972.   /* converts in from a pixel position in local coordinates to
  973.     a character cell position within the virtual screen corresponding
  974.     to the specified window. Constrains the position to lie within
  975.     the currently-visible region of the screen, autoscrolling the
  976.     screen if necessary (and if autoScroll = TRUE). */
  977.   {
  978.  
  979.     if (in.v <0)
  980.       {
  981.         in.v = 0;
  982.         if (autoScroll)
  983.             VSscrolback(w, 1);
  984.       } /* if */
  985.     if (in.v > RSlocal[w].height)
  986.       {
  987.         in.v = RSlocal[w].height;
  988.         if (autoScroll)
  989.             VSscrolforward(w, 1);
  990.       } /* if */
  991.     in.v = in.v / FHeight;
  992.  
  993.     if (in.h < 0)
  994.       {
  995.         in.h = -1;
  996.         if (autoScroll)
  997.             VSscrolleft(w, 1);
  998.       } /* if */
  999.     if (in.h > RSlocal[w].width)
  1000.       {
  1001.         in.h = RSlocal[w].width;
  1002.         if (autoScroll)
  1003.             VSscrolright(w, 1);
  1004.       } /* if */
  1005.   /* in.h = (in.h + Fwidthhalf) / FWidth - 1; */
  1006.   /* the MPW C 3.0 compiler has a bug in its register allocation */
  1007.   /* which keeps the above line from working. So, replace it with this: */
  1008.     in.h = in.h + Fwidthhalf;
  1009.     in.h = in.h / FWidth - 1;
  1010.   /* note the bug has been fixed in the 3.1 compiler. */
  1011.   /* convert to virtual screen coordinates */
  1012.     in.v += RSlocal[w].topline;
  1013.     in.h += RSlocal[w].leftmarg;
  1014.     return(in);
  1015.   } /* normalize */
  1016.  
  1017.     
  1018.  
  1019. void    RSsortAnchors(short w)
  1020. {
  1021.     Point    temp;
  1022.     
  1023.     if (RSlocal[w].anchor.v > RSlocal[w].last.v) {
  1024.         temp = RSlocal[w].anchor;
  1025.         RSlocal[w].anchor = RSlocal[w].last;
  1026.         RSlocal[w].last = temp;
  1027.         }
  1028.         
  1029.     if ((RSlocal[w].anchor.v == RSlocal[w].last.v) && (RSlocal[w].anchor.h > RSlocal[w].last.h)) {
  1030.         temp = RSlocal[w].anchor;
  1031.         RSlocal[w].anchor = RSlocal[w].last;
  1032.         RSlocal[w].last = temp;
  1033.         }
  1034. }    
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040. void    RSsetsize( short w, short v, short h)
  1041. /*    saves the new size settings for a window, and repositions
  1042.     the scroll bars accordingly. */
  1043. {
  1044.     RSlocal[w].height = ((v - 16 + CVO) / FHeight) * FHeight;
  1045.     RSlocal[w].width = ((h - 16 + CHO) / FWidth) * FWidth;
  1046.     RSlocal[w].rheight = v - 16;
  1047.     RSlocal[w].rwidth = h - 16;
  1048.  
  1049. /*
  1050. *  Get rid of the scroll bars which were in the old size.
  1051. *  Hiding them causes the region to be updated later.
  1052. */
  1053.     if (RSlocal[w].scroll != NULL )
  1054.         HideControl(RSlocal[w].scroll);
  1055.     if (RSlocal[w].left != NULL ) 
  1056.         HideControl(RSlocal[w].left);
  1057.  
  1058.      DrawGrowIcon(RSlocal[w].window);            /* Draw in the necessary bugger */
  1059.  
  1060. /*    move the scroll bars to their new positions and sizes, and redisplay them */    
  1061.  
  1062.     SetCtlValue(RSlocal[w].scroll, RSlocal[w].current); //because we dont always have this
  1063.     if (RSlocal[w].scroll != NULL ) {
  1064.         SizeControl(RSlocal[w].scroll, 16, (v - 13));
  1065.         MoveControl(RSlocal[w].scroll, (h - 15) + CHO, -1 + CVO);
  1066.         ShowControl(RSlocal[w].scroll);
  1067.         }
  1068.     if (RSlocal[w].left != NULL ) {
  1069.         SizeControl(RSlocal[w].left, (h - 13), 16);
  1070.         MoveControl(RSlocal[w].left, -1 + CHO,  (v - 15) + CVO);
  1071.         ShowControl(RSlocal[w].left);
  1072.         }
  1073.         
  1074.     SetRect(&RSlocal[w].textrect, 0, 0, RSlocal[w].rwidth, RSlocal[w].rheight);
  1075.     
  1076. } /* RSsetsize */
  1077.  
  1078.  
  1079.  
  1080. /*--------------------------------------------------------------------------*/
  1081. /* NCSA: SB - RSbackground                                                    */
  1082. /*    This procedure allows Telnet to switch from dark background to light    */
  1083. /*    background.  Save the current state into the RSdata struct, so that        */
  1084. /*     we know our background state next time we want to do anything.            */
  1085. /*    Make sure the screen contents (and palette) is updated NOW.                */
  1086. /*--------------------------------------------------------------------------*/
  1087. void RSbackground(short w, short value)
  1088. {
  1089.     RGBColor temp1,temp2;
  1090.     
  1091.     RSsetwind(w);
  1092.     if ((value && !RSlocal[w].flipped) || (!value && RSlocal[w].flipped))
  1093.     {    
  1094.         RSlocal[w].flipped = !RSlocal[w].flipped;
  1095.  
  1096.         if (TelInfo->haveColorQuickDraw) //flip the background and foreground color positions
  1097.         {
  1098.             GetEntryColor(RSlocal[w].pal,0,&temp1);
  1099.             GetEntryColor(RSlocal[w].pal,1,&temp2);
  1100.             SetEntryColor(RSlocal[w].pal,0,&temp2);
  1101.             SetEntryColor(RSlocal[w].pal,1,&temp1);
  1102.         }
  1103.         SetPort(RSlocal[w].window);
  1104.         InvalRect(&RSlocal[w].window->portRect);
  1105.         
  1106.     }
  1107. }
  1108. void RScheckmaxwind(Rect *origRect,short origW, 
  1109.             short origH, short *endW, short *endH)
  1110. {
  1111.     Rect *grayRect;
  1112.     *endW = origW;
  1113.     *endH = origH;
  1114.     
  1115.     grayRect = &((*TelInfo->greyRegion)->rgnBBox);
  1116.  
  1117.     if (origW > (grayRect->right - origRect->left))
  1118.         *endW = grayRect->right - origRect->left;
  1119.  
  1120.     if (origH > (grayRect->bottom - origRect->top -15 ))
  1121.         *endH = grayRect->bottom - origRect->top;
  1122. }